package ink.mint.loss;

import ink.mint.neural.Layer;

public interface Lossable {

    /**
     * 设置网络层
     * @param layer 网络层
     * @return 损失函数
     */
    LossFunction setLayer(Layer layer);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数的解
     */
    double LossSolve(double expectations, double output, LossType lossType, double delta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数的解
     */
    double LossSolve(double[] expectations, double[] output, LossType lossType, double delta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数的解
     */
    double LossSolve(double[][] expectations, double[][] output, LossType lossType, double delta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数的解
     */
    double LossSolve(double expectations, double output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数的解
     */
    double LossSolve(double[] expectations, double[] output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数的解
     */
    double LossSolve(double[][] expectations, double[][] output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数的解
     */
    double LossSolve(double expectations, double output, LossType lossType);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数的解
     */
    double LossSolve(double[] expectations, double[] output, LossType lossType);

    /**
     * 损失函数的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数的解
     */
    double LossSolve(double[][] expectations, double[][] output, LossType lossType);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数求导的解
     */
    double derivationLossSolve(double expectations, double output, LossType lossType, double delta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数求导的解
     */
    double[] derivationLossSolve(double[] expectations, double[] output, LossType lossType, double delta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Huber损失函数
     * @param delta        Huber损失函数的delta超参数
     * @return huber损失函数求导的解
     */
    double[][] derivationLossSolve(double[][] expectations, double[][] output, LossType lossType, double delta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数求导的解
     */
    double derivationLossSolve(double expectations, double output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数求导的解
     */
    double[] derivationLossSolve(double[] expectations, double[] output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:Focal损失函数
     * @param alpha        Focal损失函数的alpha超参数
     * @param beta         Focal损失函数的beta超参数
     * @return Focal损失函数求导的解
     */
    double[][] derivationLossSolve(double[][] expectations, double[][] output, LossType lossType, double alpha, double beta);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数求导的解
     */
    double derivationLossSolve(double expectations, double output, LossType lossType);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数求导的解
     */
    double[] derivationLossSolve(double[] expectations, double[] output, LossType lossType);

    /**
     * 损失函数求导的解
     *
     * @param expectations 期望
     * @param output       输出
     * @param lossType     损失函数类型:均方误差损失函数（MSE）、L2损失函数、L1损失函数、Smooth L1损失函数、KL散度函数（相对熵）、交叉熵损失、softmax损失函数
     * @return 损失函数求导的解
     */
    double[][] derivationLossSolve(double[][] expectations, double[][] output, LossType lossType);

    /**
     * 均方误差损失函数（MSE）
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return 均方误差损失函数（MSE）的解（标量）
     */
    double meanSquareErrorLossFunction(double expectations, double output);

    /**
     * 均方误差损失函数（MSE）
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return 均方误差损失函数（MSE）的解（标量）
     */
    double meanSquareErrorLossFunction(double[] expectations, double[] output);

    /**
     * 均方误差损失函数（MSE）
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return 均方误差损失函数（MSE）的解（标量）
     */
    double meanSquareErrorLossFunction(double[][] expectations, double[][] output);

    /**
     * L2损失函数
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return L2损失函数的解（标量）
     */
    double l2LossFunction(double expectations, double output);

    /**
     * L2损失函数
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return L2损失函数的解（标量）
     */
    double l2LossFunction(double[] expectations, double[] output);

    /**
     * L2损失函数
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return L2损失函数的解（标量）
     */
    double l2LossFunction(double[][] expectations, double[][] output);

    /**
     * L1损失函数
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return L2损失函数的解（标量）
     */
    double l1LossFunction(double expectations, double output);

    /**
     * L1损失函数
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return L2损失函数的解（标量）
     */
    double l1LossFunction(double[] expectations, double[] output);

    /**
     * L1损失函数
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return L2损失函数的解（标量）
     */
    double l1LossFunction(double[][] expectations, double[][] output);

    /**
     * Smooth L1损失函数
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return Smooth L1损失函数的解（标量）
     */
    double smoothL1LossFunction(double expectations, double output);

    /**
     * Smooth L1损失函数
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return Smooth L1损失函数的解（标量）
     */
    double smoothL1LossFunction(double[] expectations, double[] output);

    /**
     * Smooth L1损失函数
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return Smooth L1损失函数的解（标量）
     */
    double smoothL1LossFunction(double[][] expectations, double[][] output);


    /**
     * huber损失函数
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return huber损失函数的解（标量）
     */
    double huBerLossFunction(double expectations, double output, double delta);

    /**
     * huber损失函数
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return huber损失函数的解（标量）
     */
    double huBerLossFunction(double[] expectations, double[] output, double delta);

    /**
     * huber损失函数
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return huber损失函数的解（标量）
     */
    double huBerLossFunction(double[][] expectations, double[][] output, double delta);

    /**
     * KL散度函数（相对熵）
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return KL散度函数（相对熵）的解（标量）
     */
    double kullbackLeiblerDivergenceFunction(double expectations, double output);

    /**
     * KL散度函数（相对熵）
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return KL散度函数（相对熵）的解（标量）
     */
    double kullbackLeiblerDivergenceFunction(double[] expectations, double[] output);

    /**
     * KL散度函数（相对熵）
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return KL散度函数（相对熵）的解（标量）
     */
    double kullbackLeiblerDivergenceFunction(double[][] expectations, double[][] output);

    /**
     * 交叉熵损失
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return 交叉熵损失的解（标量）
     */
    double crossEntropyLossFunction(double expectations, double output);

    /**
     * 交叉熵损失
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return 交叉熵损失的解（标量）
     */
    double crossEntropyLossFunction(double[] expectations, double[] output);

    /**
     * 交叉熵损失
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return 交叉熵损失的解（标量）
     */
    double crossEntropyLossFunction(double[][] expectations, double[][] output);

    /**
     * softmax损失函数
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return softmax损失函数的解（标量）
     */
    double softmaxLossFunction(double expectations, double output);

    /**
     * softmax损失函数
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return softmax损失函数的解（标量）
     */
    double softmaxLossFunction(double[] expectations, double[] output);

    /**
     * softmax损失函数
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return softmax损失函数的解（标量）
     */
    double softmaxLossFunction(double[][] expectations, double[][] output);

    /**
     * FocalLoss (局灶性损失函数)
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @param alpha        解决正负样本不均衡的 alpha 值
     * @param beta         解决难样本 beta 值
     * @return FocalLoss (局灶性损失函数)的解（标量）
     */
    double focalLossFunction(double expectations, double output, double alpha, double beta);

    /**
     * FocalLoss (局灶性损失函数)
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @param alpha        解决正负样本不均衡的 alpha 值
     * @param beta         解决难样本 beta 值
     * @return FocalLoss (局灶性损失函数)的解（标量）
     */
    double focalLossFunction(double[] expectations, double[] output, double alpha, double beta);

    /**
     * FocalLoss (局灶性损失函数)
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @param alpha        解决正负样本不均衡的 alpha 值
     * @param beta         解决难样本 beta 值
     * @return FocalLoss (局灶性损失函数)的解（标量）
     */
    double focalLossFunction(double[][] expectations, double[][] output, double alpha, double beta);

    /**
     * 均方误差损失函数（MSE）    求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return 均方误差损失函数（MSE）的解（标量）
     */
    double derivationMeanSquareErrorLossFunction(double expectations, double output);

    /**
     * 均方误差损失函数（MSE）    求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return 均方误差损失函数（MSE）的解（向量）
     */
    double[] derivationMeanSquareErrorLossFunction(double[] expectations, double[] output);

    /**
     * 均方误差损失函数（MSE）    求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return 均方误差损失函数（MSE）的解（矩阵）
     */
    double[][] derivationMeanSquareErrorLossFunction(double[][] expectations, double[][] output);

    /**
     * L2损失函数   求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return L2损失函数的解（标量）
     */
    double derivationL2LossFunction(double expectations, double output);

    /**
     * L2损失函数   求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return L2损失函数的解（向量）
     */
    double[] derivationL2LossFunction(double[] expectations, double[] output);

    /**
     * L2损失函数   求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return L2损失函数的解（矩阵）
     */
    double[][] derivationL2LossFunction(double[][] expectations, double[][] output);

    /**
     * L1损失函数   求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return L2损失函数的解（标量）
     */
    double derivationL1LossFunction(double expectations, double output);

    /**
     * L1损失函数   求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return L2损失函数的解（向量）
     */
    double[] derivationL1LossFunction(double[] expectations, double[] output);

    /**
     * L1损失函数   求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return L2损失函数的解（矩阵）
     */
    double[][] derivationL1LossFunction(double[][] expectations, double[][] output);

    /**
     * Smooth L1损失函数    求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return Smooth L1损失函数的解（标量）
     */
    double derivationSmoothL1LossFunction(double expectations, double output);

    /**
     * Smooth L1损失函数    求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return Smooth L1损失函数的解（向量）
     */
    double[] derivationSmoothL1LossFunction(double[] expectations, double[] output);

    /**
     * Smooth L1损失函数    求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return Smooth L1损失函数的解（矩阵）
     */
    double[][] derivationSmoothL1LossFunction(double[][] expectations, double[][] output);

    /**
     * huber损失函数    求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return huber损失函数的解（标量）
     */
    double derivationHuBerLossFunction(double expectations, double output);

    /**
     * huber损失函数    求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return huber损失函数的解（向量）
     */
    double[] derivationHuBerLossFunction(double[] expectations, double[] output);

    /**
     * huber损失函数    求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return huber损失函数的解（矩阵）
     */
    double[][] derivationHuBerLossFunction(double[][] expectations, double[][] output);

    /**
     * KL散度函数（相对熵）  求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return KL散度函数（相对熵）的解（标量）
     */
    double derivationKullbackLeiblerDivergenceFunction(double expectations, double output);

    /**
     * KL散度函数（相对熵）  求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return KL散度函数（相对熵）的解（向量）
     */
    double[] derivationKullbackLeiblerDivergenceFunction(double[] expectations, double[] output);

    /**
     * KL散度函数（相对熵）  求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return KL散度函数（相对熵）的解（矩阵）
     */
    double[][] derivationKullbackLeiblerDivergenceFunction(double[][] expectations, double[][] output);

    /**
     * 交叉熵损失    求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return 交叉熵损失的解（标量）
     */
    double derivationCrossEntropyLossFunction(double expectations, double output);

    /**
     * 交叉熵损失    求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return 交叉熵损失的解（向量）
     */
    double[] derivationCrossEntropyLossFunction(double[] expectations, double[] output);

    /**
     * 交叉熵损失    求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return 交叉熵损失的解（矩阵）
     */
    double[][] derivationCrossEntropyLossFunction(double[][] expectations, double[][] output);

    /**
     * softmax损失函数  求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return softmax损失函数的解（标量）
     */
    double derivationSoftmaxLossFunction(double expectations, double output);

    /**
     * softmax损失函数  求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return softmax损失函数的解（向量）
     */
    double[] derivationSoftmaxLossFunction(double[] expectations, double[] output);

    /**
     * softmax损失函数  求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return softmax损失函数的解（矩阵）
     */
    double[][] derivationSoftmaxLossFunction(double[][] expectations, double[][] output);

    /**
     * FocalLoss (局灶性损失函数)  求导
     *
     * @param expectations 期望值（标量）
     * @param output       输出值（标量）
     * @return FocalLoss (局灶性损失函数)的解（标量）
     */
    double derivationFocalLossFunction(double expectations, double output);

    /**
     * FocalLoss (局灶性损失函数)  求导
     *
     * @param expectations 期望值（向量）
     * @param output       输出值（向量）
     * @return FocalLoss (局灶性损失函数)的解（向量）
     */
    double[] derivationFocalLossFunction(double[] expectations, double[] output);

    /**
     * FocalLoss (局灶性损失函数)  求导
     *
     * @param expectations 期望值（矩阵）
     * @param output       输出值（矩阵）
     * @return FocalLoss (局灶性损失函数)的解（矩阵）
     */
    double[][] derivationFocalLossFunction(double[][] expectations, double[][] output);
}
